local app = require "app"
local blaze = require "blaze"
local game = require "club.threecard.sudoku"
local Cell = require "club.threecard.sudoku.ui.ingame.Cell"

local M = game.ui.element()

local log = blaze.logging.get("Board")

M.store_watchers = {
    ingame = {
        ["$"] = function(self, store, state, args)
            self:init(state)
        end,
        ["初始化面板"] = function(self, store, state, args)
            if #self.cells == #state.cells then
                self:init(state)
            end
        end,
        ["清理"] = function(self, store, state, player)
            self:hide_cells()
        end,
        ["解答正确"] = function(self, store, state, args)
            local cell = self.cells[args.index + 1]
            cell:update_color(args)
            cell:set_value(args.value)
            game.audio.post("correct")
        end,
        ["解答错误"] = function(self, store, state, args)
            local cell = self.cells[args.index + 1]
            cell:update_color(args)
            cell:force_wrong_color()
            cell:set_value(args.error)
            game.audio.post("incorrect")
        end,
        ["选中格子"] = function(self, store, state, args)
            local cell = self.cells[args.index + 1]
            cell:update_color(args)
        end,
        ["取消选中格子"] = function(self, store, state, args)
            local cell = self.cells[args.index + 1]
            cell:update_color(args)
        end,
        ["格子样式变更"] = function(self, store, state, args)
            local cell = self.cells[args.index + 1]
            cell:update_color(args)
        end,
        ["标记数字变更"] = function(self, store, state, args)
            local cell = self.cells[args.index + 1]
            cell:update_candidates(args)
        end
    }
}

function M:ctor(size)
    self.res = "club.threecard.sudoku/ui/ingame.b:board" .. tostring(size)
    self.size = size
    local cells = {}
    local cells_by_pos = {}
    for y = 0, size - 1 do
        for x = 0, size - 1 do
            local cell = Cell.new(self, x, y)
            cells[#cells + 1] = cell
            cells_by_pos[y * 10 + x] = cell
        end
    end
    self.cells_by_pos = cells_by_pos
    self.cells = cells
end

function M:init(state)
    if #state.cells == 0 then
        return
    end
    assert(#self.cells == #state.cells, string.format("%s~=%s", #self.cells, #state.cells))
    for i, info in ipairs(state.cells) do
        local cell = self.cells[i]
        cell:set_position(info.x, info.y)
        cell:set_value(info.value)
        cell:update_color(info)
        self.cells_by_pos[info.y * 10 + info.x] = cell
    end
    if state.phase_id == 1 then
        -- 准备阶段隐藏
        self:hide_cells()
    elseif state.phase_id == 2 then
        -- 解谜阶段显示
        self:show_cells()
    end
end

function M:load()
    self:super("load")
    for _, cell in ipairs(self.cells) do
        cell:load()
    end
end

function M:on_injected(bind)
    for _, cell in ipairs(self.cells) do
        local name = string.format("%d%d", cell.x, cell.y) 
        local cell_transform = self.cells_root:Find(name)
        cell:set_gameobject(cell_transform.gameObject, true)
    end
end

function M:on_cell_click(cell)
    game.store.ingame.select(cell)
end

function M:hide_cells()
    for _, cell in ipairs(self.cells) do
        cell:hide_value()
        cell:hide_candidates()
    end
end

function M:show_cells()
    for _, cell in ipairs(self.cells) do
        cell:show_value()
    end
end

return M